import {
  getThemeColor,
  ORIGINAL_THEME_COLOR,
  getUserInfoFromStorage,
  setThemeColor,
  setToken,
  setUserInfoToStorage,
  setExpire
} from '@/utils';

import { login } from '@/api/sysUser';
import {
  loadApplicationIdByMenuList,
  loadUserIdByApplicationList
} from '@/api/sysRoleApplication';
import { loadApplicationIdByMenuAddress } from '@/api/sysMenu';
import { getAreaList } from '@/api/energyConsumption';
import { getFirstMenuPath } from '@/router';
import Layout from '@/layout';

function createRoutes(menuTree) {
  return menuTree.reduce((acc, menu) => {
    const route = {};
    if (menu.menuType < 2) {
      route.path = menu.menuAddress;
      route.meta = {
        title: menu.menuTitle,
        applicationId: menu.applicationId,
        applicationName: menu.applicationName,
        id: menu.id,
        superiorMenuId: menu.superiorMenuId
      };
      route.id = menu.id;
      route.superiorMenuId = menu.superiorMenuId;
      route.hidden = menu.hidden;
      if (menu.menuIcon) {
        route.meta.icon = menu.menuIcon;
      }
      if (menu.menuName) {
        route.name = menu.menuName;
      }
      if (menu.menuType === 0) {
        route.component = Layout;
      } else if (menu.menuType === 1) {
        route.component = () => import(`@/views${menu.menuAddress}`);
      }
      if (menu.children && menu.children.length > 0) {
        route.children = createRoutes(menu.children);
      }
      acc = acc.concat([route]);
    }
    return acc;
  }, []);
}

export default {
  namespaced: true,
  state: {
    theme: getThemeColor() || ORIGINAL_THEME_COLOR,
    userInfo: getUserInfoFromStorage(),
    userApps: [],
    currentAppId: null,
    permissionRoutes: [],
    cityCode: '321000',
    districtsList: {}
  },
  getters: {
    districts(state) {
      return Object.keys(state.districtsList).map(code => ({
        code,
        name: state.districtsList[code],
      }));
    }
  },
  mutations: {
    SET_USER_INFO(state, payload) {
      state.userInfo = { ...payload };
      setUserInfoToStorage(payload);
    },
    SET_THEME(state, color) {
      state.theme = color;
      setThemeColor(color);
    },
    SET_PERMISSION_ROUTES(state, routes) {
      state.permissionRoutes = [...routes];
    },
    SET_USER_APPS(state, apps) {
      state.userApps = [...apps];
    },
    SET_CURRENT_APP_ID(state, applicationId) {
      state.currentAppId = applicationId;
    },
    SET_DISTRICTS_LIST(state, payload) {
      state.districtsList = { ...payload };
    }
  },
  actions: {
    login({ commit }, { loginName, passWord, accountType = '' }) {
      return login({
        loginName,
        passWord,
        accountType
      }).then(res => {
        if (res.code === 200) {
          const { tk, ...rest } = res.data;
          commit('SET_USER_INFO', rest);
          setToken(tk);
          setExpire(Date.now());
        }
      });
    },
    getPermissionApps({ commit }) {
      return new Promise((resolve, reject) => {
        loadUserIdByApplicationList().then(res => {
          if (res.code === 200) {
            commit('SET_USER_APPS', res.data);
            resolve(res.data);
          } else {
            reject(new Error(res.message));
          }
        });
      });
    },
    getPermissionRoutesByAppId({ commit, state }, applicationId) {
      return new Promise((resolve, reject) => {
        loadApplicationIdByMenuList(applicationId)
          .then(res => {
            if (res.code === 200) {
              const permissionRoutes = createRoutes(res.data);
              // console.log(permissionRoutes)
              resolve(permissionRoutes);
            } else {
              reject(new Error(res.message));
            }
          })
          .catch(err => reject(err));
      });
    },
    getApplicationIdByPath({ dispatch, commit, state }, path) {
      return new Promise((resolve, reject) => {
        if (path === '/') {
          dispatch('getPermissionApps').then(apps => {
            const applicationId = apps && apps[0] ? apps[0].id : null;
            if (applicationId) {
              commit('SET_CURRENT_APP_ID', applicationId);
              resolve(applicationId);
            } else {
              reject(new Error('没有设置应用'));
            }
          });
        } else {
          loadApplicationIdByMenuAddress(path).then(res => {
            if (res.code === 200) {
              const applicationId = res.data;
              if (applicationId) {
                commit('SET_CURRENT_APP_ID', applicationId);
              }
              resolve(applicationId);
            } else {
              reject(new Error(res.message));
            }
          });
        }
      });
    },
    switchApps({ commit, dispatch }, applicationId) {
      return new Promise((resolve, reject) => {
        commit('SET_CURRENT_APP_ID', applicationId);
        dispatch('getPermissionRoutesByAppId', applicationId).then(routes => {
          commit('SET_PERMISSION_ROUTES', routes);
          if (routes && routes[0]) {
            resolve(getFirstMenuPath(routes[0]));
          } else {
            reject(new Error('该应用下没有菜单'));
          }
        });
      });
    },
    generateRoutes({ dispatch, commit, state }) {
      return new Promise((resolve, reject) => {
        const userInfo = state.userInfo;
        let applicationIds = userInfo.applicationIds;
        applicationIds = applicationIds ? applicationIds.split(',') : [];

        if (applicationIds[0]) {
          commit('SET_CURRENT_APP_ID', applicationIds[0]);
        }

        const rqs = applicationIds.map(applicationId => {
          return dispatch('getPermissionRoutesByAppId', applicationId);
        });
        if (rqs.length < 1) {
          return reject(new Error('无效路径'));
        }
        Promise.all(rqs).then(routesArray => {
          const routes = routesArray.reduce((acc, v) => {
            acc = acc.concat(v);
            return acc;
          }, []);
          commit('SET_PERMISSION_ROUTES', routes);
          resolve(routes);
        });
      });
    },
    getDistrictsList({ commit, state }) {
      return new Promise(resolve => {
        if (state.districtsList.length > 0) {
          resolve(state.districtsList);
        } else {
          getAreaList()
            .then(res => {
              resolve(res.data);
              commit('SET_DISTRICTS_LIST', res.data);
            })
            .catch(e => {
              console.warn(e);
              resolve({});
            });
        }
      });
    }
  }
};
